package com.ruoyi.zhgd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.zhgd.domain.bo.YLJReportBo;
import com.ruoyi.zhgd.domain.vo.YLJBGVo;
import com.ruoyi.zhgd.domain.vo.YLJJLVo;
import com.ruoyi.zhgd.domain.vo.YLJReportVo;
import com.ruoyi.system.domain.ZjSysContract;
import com.ruoyi.system.domain.vo.ZjSysContractVo;
import com.ruoyi.system.domain.vo.ZjSysProjectVo;
import com.ruoyi.system.mapper.ZjSysContractMapper;
import com.ruoyi.system.mapper.ZjSysProjectMapper;
import com.ruoyi.zhgd.domain.vo.NLaboratoryMechanicsYGroupReportVo;
import com.ruoyi.zhgd.domain.vo.ZjNWarningUsingVo;
import com.ruoyi.zhgd.service.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.zhgd.domain.bo.NLaboratoryMechanicsYGroupBo;
import com.ruoyi.zhgd.domain.vo.NLaboratoryMechanicsYGroupVo;
import com.ruoyi.zhgd.domain.NLaboratoryMechanicsYGroup;
import com.ruoyi.zhgd.mapper.NLaboratoryMechanicsYGroupMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;


/**
 * 压力机数据主Service业务层处理
 *
 * @author zyb
 * @date 2023-09-11
 */
@RequiredArgsConstructor
@Service
@DS("sjcj")
@Slf4j
public class NLaboratoryMechanicsYGroupServiceImpl implements INLaboratoryMechanicsYGroupService {

    private final NLaboratoryMechanicsYGroupMapper baseMapper;

    @Autowired
    private IZjStressRequiresService requiresService;

    @Autowired
    private INLaboratoryMechanicsYDetailService yDetailService;

    @Autowired
    private IZjWarningSyService warningSyService;
    @Autowired
    private IZjNWarningUserMessageService messageService;

    @Autowired
    private IZjNWarningUsingService usingService;

    private final ZjSysContractMapper zjSysContractMapper;
    private final ZjSysProjectMapper zjSysProjectMapper;

    /**
     * 查询压力机数据主
     */
    @Override
    public NLaboratoryMechanicsYGroupVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询压力机数据主列表
     */
    @Override
    public TableDataInfo<NLaboratoryMechanicsYGroupVo> queryPageList(NLaboratoryMechanicsYGroupBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<NLaboratoryMechanicsYGroup> lqw = buildQueryWrapper(bo);
        Page<NLaboratoryMechanicsYGroupVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询压力机数据主列表
     */
    @Override
    public List<NLaboratoryMechanicsYGroupVo> queryList(NLaboratoryMechanicsYGroupBo bo) {
        LambdaQueryWrapper<NLaboratoryMechanicsYGroup> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<NLaboratoryMechanicsYGroup> buildQueryWrapper(NLaboratoryMechanicsYGroupBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<NLaboratoryMechanicsYGroup> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getSourceId() != null, NLaboratoryMechanicsYGroup::getSourceId, bo.getSourceId());
        lqw.eq(StringUtils.isNotBlank(bo.getSYLX()), NLaboratoryMechanicsYGroup::getSYLX, bo.getSYLX());
        lqw.eq(StringUtils.isNotBlank(bo.getSYBH()), NLaboratoryMechanicsYGroup::getSYBH, bo.getSYBH());
        lqw.eq(bo.getSYSL() != null, NLaboratoryMechanicsYGroup::getSYSL, bo.getSYSL());
        lqw.eq(StringUtils.isNotBlank(bo.getLQ()), NLaboratoryMechanicsYGroup::getLQ, bo.getLQ());
        lqw.eq(StringUtils.isNotBlank(bo.getShape()), NLaboratoryMechanicsYGroup::getShape, bo.getShape());
        lqw.eq(StringUtils.isNotBlank(bo.getSize()), NLaboratoryMechanicsYGroup::getSize, bo.getSize());
        lqw.eq(bo.getXS() != null, NLaboratoryMechanicsYGroup::getXS, bo.getXS());
        lqw.eq(StringUtils.isNotBlank(bo.getQDDJ()), NLaboratoryMechanicsYGroup::getQDDJ, bo.getQDDJ());
        lqw.eq(StringUtils.isNotBlank(bo.getPingZhong()), NLaboratoryMechanicsYGroup::getPingZhong, bo.getPingZhong());
        lqw.eq(bo.getYXLZ() != null, NLaboratoryMechanicsYGroup::getYXLZ, bo.getYXLZ());
        lqw.eq(StringUtils.isNotBlank(bo.getYXQD()), NLaboratoryMechanicsYGroup::getYXQD, bo.getYXQD());
        lqw.eq(StringUtils.isNotBlank(bo.getPDJG()), NLaboratoryMechanicsYGroup::getPDJG, bo.getPDJG());
        lqw.eq(bo.getSYSJ() != null, NLaboratoryMechanicsYGroup::getSYSJ, bo.getSYSJ());
        lqw.eq(StringUtils.isNotBlank(bo.getMachine()), NLaboratoryMechanicsYGroup::getMachine, bo.getMachine());
        lqw.eq(StringUtils.isNotBlank(bo.getTester()), NLaboratoryMechanicsYGroup::getTester, bo.getTester());
        lqw.eq(bo.getTag() != null, NLaboratoryMechanicsYGroup::getTag, bo.getTag());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), NLaboratoryMechanicsYGroup::getType, bo.getType());
        lqw.eq(bo.getCreateDate() != null, NLaboratoryMechanicsYGroup::getCreateDate, bo.getCreateDate());
        lqw.eq(StringUtils.isNotBlank(bo.getSpeed()), NLaboratoryMechanicsYGroup::getSpeed, bo.getSpeed());
        lqw.eq(StringUtils.isNotBlank(bo.getKj()), NLaboratoryMechanicsYGroup::getKj, bo.getKj());
        lqw.eq(StringUtils.isNotBlank(bo.getMj()), NLaboratoryMechanicsYGroup::getMj, bo.getMj());
        lqw.eq(StringUtils.isNotBlank(bo.getSjwj()), NLaboratoryMechanicsYGroup::getSjwj, bo.getSjwj());
        lqw.eq(StringUtils.isNotBlank(bo.getXsok()), NLaboratoryMechanicsYGroup::getXsok, bo.getXsok());
        return lqw;
    }

    /**
     * 新增压力机数据主
     */
    @Override
    public Boolean insertByBo(NLaboratoryMechanicsYGroupBo bo) {
        NLaboratoryMechanicsYGroup add = BeanUtil.toBean(bo, NLaboratoryMechanicsYGroup.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改压力机数据主
     */
    @Override
    public Boolean updateByBo(NLaboratoryMechanicsYGroupBo bo) {
        NLaboratoryMechanicsYGroup update = BeanUtil.toBean(bo, NLaboratoryMechanicsYGroup.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Boolean insertOrUpdateBatchByBoList(YLJReportBo reportBo) {
        reportBo.getBos().forEach(v -> {
            BeanUtil.copyProperties(reportBo.getBs(), v);
        });
        List<NLaboratoryMechanicsYGroup> yGroupList = BeanUtil.copyToList(reportBo.getBos(), NLaboratoryMechanicsYGroup.class);
        return baseMapper.insertOrUpdateBatch(yGroupList);
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(NLaboratoryMechanicsYGroup entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除压力机数据主
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 压力机设备信息列表
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<NLaboratoryMechanicsYGroupVo> page(NLaboratoryMechanicsYGroupBo bo, PageQuery pageQuery) {
        Page<NLaboratoryMechanicsYGroupVo> result = baseMapper.page(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void verifyEligible(Integer id) {
        //预警信息
        String remark = "";
        //默认合格
        Integer eligible = 1;
        //查询采集数据试验名称、所属单位、强度等级、试验编号
        NLaboratoryMechanicsYGroupVo vo = baseMapper.selectMap(id);
        String pdjg = vo.getPDJG();

        if ("不合格".equals(pdjg)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            eligible = 0;
            remark = vo.getDeptName() + "试验时间：" + sdf.format(vo.getSYSJ()) + "，试验名称：" + vo.getSymc() + "，试验编号：" +
                vo.getSYBH() + "，强度等级:" + vo.getQDDJ() + "，有效强度:" + vo.getYXQD() + "不合格。";
        } else if (StringUtils.isEmpty(pdjg) && "28".equals(vo.getLQ()) && vo.getYXQD() != null) {
            //查询技术参数
            String symc = vo.getSymc();
            if (StringUtils.isNotBlank(symc)) {
                if (symc.indexOf("KZ") != -1 || symc.indexOf("抗折") != -1) {
                    symc = "'%抗折%'";
                } else {
                    symc = "'%抗压%'";
                }
            }
            Float requires = requiresService.selectRequires(symc, vo.getQDDJ());
            if (Float.valueOf(vo.getYXQD()) < requires) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                eligible = 0;
                pdjg = "不合格";
                remark = vo.getDeptName() + "试验时间：" + sdf.format(vo.getSYSJ()) + "，试验名称：" + vo.getSymc() + "，试验编号：" +
                    vo.getSYBH() + "，强度等级:" + vo.getQDDJ() + "，有效强度:" + vo.getYXQD() + "不合格。";
            } else {
                pdjg = "合格";
            }

        }

//        if (vo.getLQ() != null && vo.getLQ().equals("28")) {
//            //查询采集数据详情
//            List<NLaboratoryMechanicsYDetail> yDetail = yDetailService.selectyDetail(id);
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            //查询技术参数
//            Float requires = requiresService.selectRequires(null, vo.getQDDJ());
//            int size = yDetail.size();
//            if (size != 0 && size % 3 == 0) {
//                float stress = 0;
//                int count = 0;
//                for(NLaboratoryMechanicsYDetail detail : yDetail) {
//                    count++;
//                    stress += detail.getStress();
//                    if (count % 3 == 0) {
//                        count = 0;
//                        stress = stress / 3;
//                        if (stress < requires) {
//                            eligible = 0;
//                            remark = vo.getDeptName() + "试验时间：" + sdf.format(vo.getSYSJ()) + "，试验名称：" + vo.getSymc() + "，试验编号：" +
//                                vo.getSYBH() + "，强度等级:" + vo.getQDDJ() + "，有效强度:" + stress + "不合格。";
//                            break;
//                        }
//                        stress = 0;
//                    }
//                }
//            }
//        }
        //修改合格参数
        baseMapper.updateEligible(id, eligible, pdjg);
        if (eligible == 0) {
            // 发送预警信息
            //查询短信开关是否开启；
            List<ZjNWarningUsingVo> warnintUsing = usingService.selectByygroupId(id);
            if (warnintUsing == null || warnintUsing.size() == 0) {
                log.info("发送短信失败......");
                return;
            } else {
                ZjNWarningUsingVo zjNWarningUsingVo = warnintUsing.get(0);
                if (zjNWarningUsingVo.getUsingMsgSy() == 0) {
                    log.info("实验室短信开关未开启");
                    return;
                }
            }
            Integer message = sendTextMessage(remark, vo.getDeptId());
            //保存预警信息
            saveWarningSy(remark, id, message, vo.getType());
        }
    }


    @Override
    public R<List<NLaboratoryMechanicsYGroupReportVo>> reportList(String sybh,Integer id) throws ParseException {
        if (sybh == null || sybh.length() == 0) {
            return R.fail("试验编号为空");
        }
        String[] sybhArray = sybh.split("-");
        String s4;
        if (sybhArray.length < 5) {
            throw new ServiceException("试验编号格式有误，请检查数据格式");
        } else if (sybhArray[4].length() > 3) {
            s4 = sybhArray[4].substring(0, 3);
        } else {
            s4 = sybhArray[4];
        }
        sybh = sybhArray[0] + "-" + sybhArray[1] + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;
        String jlbh = sybhArray[0] + "-" + "JL" + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;
        String bgbh = sybhArray[0] + "-" + "BG" + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;

        //查询采集数据试验名称、所属单位、强度等级、试验编号
        NLaboratoryMechanicsYGroupVo yGroupVo = baseMapper.selectMap(id);
        //查询技术参数
        String symc = yGroupVo.getSymc();
        if(StringUtils.isNotBlank(symc)){
            if (symc.indexOf("KZ") != -1 || symc.indexOf("抗折") != -1) {
                symc = "'%抗折%'";
            } else {
                symc = "'%抗压%'";
            }
        }

        Float requires = requiresService.selectRequires(symc, yGroupVo.getQDDJ());
        List<NLaboratoryMechanicsYGroupReportVo> list = baseMapper.selectReport(sybh);

        int count = 0;
        for (NLaboratoryMechanicsYGroupReportVo vo : list) {
            count++;
            vo.setXh(String.valueOf(count));
            vo.setJgpd("/");
            // 计算成型日期
            int lq = Integer.parseInt(vo.getLQ()) * -1;
            vo.setCxrqStr(DateUtil.parse(vo.getSyjcrqStr(), "yyyy年MM月dd日").offset(DateField.DAY_OF_MONTH, lq).toString("yyyy年MM月dd日"));
            // 计算换算后抗压强度 达到设计强度百分比%
            vo.setHshkyqd(vo.getYXQD());
            try {
                vo.setDdsjqdbfb(new BigDecimal(vo.getHshkyqd()).multiply(new BigDecimal("100")).divide(new BigDecimal(requires),1,BigDecimal.ROUND_HALF_UP).toString());
            } catch (Exception e) {
                throw new ServiceException("达到设计强度百分比计算有误，请检查数据格式是否正确");
            }

        }
        return R.ok(list);
    }

    @SneakyThrows
    @Override
    public R<List<YLJJLVo>> reportBs(String sybh,Integer id) {
        String[] sybhArray = sybh.split("-");
        String s4;
        if (sybhArray.length < 5) {
            throw new ServiceException("试验编号格式有误，请检查数据格式");
        } else if (sybhArray[4].length() > 3) {
            s4 = sybhArray[4].substring(0, 3);
        } else {
            s4 = sybhArray[4];
        }
        sybh = sybhArray[0] + "-" + sybhArray[1] + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;
        String jlbh = sybhArray[0] + "-" + "JL" + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;
        String bgbh = sybhArray[0] + "-" + "BG" + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;
        String ypbh = sybhArray[0] + "-" + "YP" + "-" + sybhArray[2] + "-" + sybhArray[3] + "-" + s4;

        int count = 0;
        R<List<NLaboratoryMechanicsYGroupReportVo>> listR = reportList(sybh,id);
        List<NLaboratoryMechanicsYGroupReportVo> list = listR.getData();
        StringBuilder conclusion = new StringBuilder("经检测，该组混凝土试件" + list.get(0).getLQ() + "天抗压强度达到设计强度的");
        for (NLaboratoryMechanicsYGroupReportVo vo : list) {
            if (count % 3 == 0) {
                conclusion.append(vo.getDdsjqdbfb() + "%，");
            }
            count++;
        }
        conclusion.append("符合设计要求。");
        YLJReportVo reportVo = new YLJReportVo();
        YLJBGVo bgVo = new YLJBGVo();
        YLJJLVo jlVo;

        if (CollectionUtil.isNotEmpty(list)) {
            Long deptId = list.get(0).getDeptId();
            // 获取合同信息
            ZjSysContractVo contract = zjSysContractMapper.selectVoOne(new LambdaQueryWrapper<ZjSysContract>()
                .eq(ZjSysContract::getDeptId, deptId));
            // 获取项目信息
            ZjSysProjectVo project = zjSysProjectMapper.selectVoById(contract.getProjectId());

            bgVo.setSgGroup(contract.getSgGroup());
            bgVo.setProjectName(project.getProjectName());
            bgVo.setJcGroup(contract.getJcGroup());
            bgVo.setBgNum(bgbh);
            bgVo.setSampleCode(ypbh);
            bgVo.setProjectPartUse(list.get(0).getProjectPartUse());
            bgVo.setSampleName(list.get(0).getHntType());
            bgVo.setSampleNum(NumberChineseFormatter.formatSimple(list.size() / 3) + "组（" + list.size() + "块）");
            bgVo.setGotDate(list.get(0).getGotDateStr());
            bgVo.setSampleIntro(StrUtil.emptyToDefault(list.get(0).getSampleIntro(), "拌合物搅拌均匀，无高析，试块表面平整，无蜂窝麻面、无破损、尺寸满足规范要求。"));
            bgVo.setCheckAccord(StrUtil.emptyToDefault(list.get(0).getCheckAccord(), "JTG 3420-2020"));
            bgVo.setJudgeAccord(StrUtil.emptyToDefault(list.get(0).getJudgeAccord(), "设计文件"));
            bgVo.setMainDeviceNameAndNum(list.get(0).getMainDeviceNameAndNum());
            bgVo.setHntType(list.get(0).getHntType());
            bgVo.setDesignClass(list.get(0).getQDDJ());
            bgVo.setStirMode(list.get(0).getStirMode());
            bgVo.setSampleSize(list.get(0).getSize());
            bgVo.setBl(list.get(0).getBl());
            bgVo.setDesignDLD(list.get(0).getDesignDLD());
            bgVo.setMaintainCondition(list.get(0).getMaintainCondition());
//            bgVo.setExperimentList(list);
            bgVo.setCheckConclusion(conclusion.toString());
            bgVo.setJlGroup(contract.getJlGroup());
//            reportVo.setBg(bgVo);

            jlVo = BeanUtil.toBean(bgVo, YLJJLVo.class);
            jlVo.setJlNum(jlbh);
            jlVo.setSyjcrq(list.get(0).getSyjcrqStr());
            jlVo.setSytj(list.get(0).getSytj());
//            reportVo.setJl(jlVo);
            ArrayList<YLJJLVo> yljjlVos = new ArrayList<>();
            yljjlVos.add(jlVo);
            return R.ok(yljjlVos);
        }

        return R.fail();
    }

    private Integer sendTextMessage(String remark, String deptId) {
        //查询发送手机号
        String warnValLab = "3";
        List<String> receiveAddr = messageService.selectReceiveAddr(deptId, warnValLab);
        Integer message = 2;
        if (receiveAddr.size() > 0) {
            message = usingService.send(receiveAddr, remark);
        }
        return message;
    }

    //保存预警信息
    private void saveWarningSy(String remark, Integer id, Integer message,String deptId) {
        String type = "1";
        warningSyService.saveWarningSy(remark, id,type, message,deptId);
    }

}
